package interactiond

import (
	"time"

	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/common"
	cinteractiond "gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/interactiond"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/repo/mgorepo/baser"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/ddd"
)

type typeRepo struct {
	baser.BaseRepo
}

func (r typeRepo) AddType(ctx ddd.Context, itype cinteractiond.TypeDesc) (err error) {
	uid := ctx.UID()
	now := time.Now()
	c := collType{
		CreTime: now,
		Creator: uid,
	}
	c.FullDesc(itype)
	return r.DBInsert(ctx, c)
}

// 获取指定类型：根据唯一标识获取类型实体
func (r typeRepo) GetType(ctx ddd.Context, code string) (*cinteractiond.TypeAggregate, error) {
	a, err := r.GetByCollAggregate(ctx, &collType{Code: code})
	if err != nil || a == nil {
		if err == mgo.ErrNotFound {
			return nil, nil
		}
		return nil, err
	}
	return a.(*cinteractiond.TypeAggregate), nil
}

// 分页获取类型列表：根据唯一标识获取下一页指定数量的类型实体集合
// total 总数量
func (r typeRepo) QueryPage(ctx ddd.Context, is cinteractiond.TypeSearch, pi common.PageInfo) (pr common.PageResult, result []cinteractiond.TypeAggregate, err error) {
	query := bson.M{}
	if is.Key != "" {
		query["$or"] = []bson.M{
			bson.M{"_id": bson.M{"$regex": is.Key}},
			bson.M{"name": bson.M{"$regex": is.Key}},
		}
	}
	if len(is.Status) > 0 {
		query["status"] = bson.M{"$in": is.Status}
	}
	var cs []collType
	pr, err = r.DBQueryPage(ctx, collNameType, pi, "_id", query, nil, nil, &cs)
	if len(cs) == 0 || err != nil {
		if err == mgo.ErrNotFound {
			err = nil
		}
		return
	}
	for _, c := range cs {
		result = append(result, *c.ToTypeAggregate())
	}
	return

}

func (r typeRepo) All(ctx ddd.Context, is cinteractiond.TypeSearch) (result []cinteractiond.TypeAggregate, err error) {
	query := bson.M{}
	if is.Key != "" {
		query["$or"] = []bson.M{
			bson.M{"_id": bson.M{"$regex": is.Key}},
			bson.M{"name": bson.M{"$regex": is.Key}},
		}
	}
	var cs []collType
	err = r.DBQuery(ctx, collNameType, query, nil, nil, &cs)
	if len(cs) == 0 || err != nil {
		if err == mgo.ErrNotFound {
			err = nil
		}
		return
	}
	for _, c := range cs {
		result = append(result, *c.ToTypeAggregate())
	}
	return

}

// 修改类型
func (r typeRepo) UpdateType(ctx ddd.Context, code string, itype *cinteractiond.TypeDesc) error {
	update := bson.M{
		"name":     itype.Name,
		"mode":     itype.Mode,
		"isPublic": itype.IsPublic,
		"isAgv":    itype.IsAgv,
		"max":      itype.Max,
		"min":      itype.Min,
		"status":   itype.Status,
	}
	return r.DBUpdateCollAggregate(ctx, &collType{Code: code}, update)

}

// 删除类型 标记删除
func (r typeRepo) DeleteType(ctx ddd.Context, code string) error {
	update := bson.M{
		"status":     cinteractiond.ITStatusDel,
		"deleteTime": time.Now(),
		"deleter":    ctx.UID(),
	}
	return r.DBUpdateCollAggregate(ctx, &collType{Code: code}, update)
}

// 删除类型 标记删除
func (r typeRepo) RecoverType(ctx ddd.Context, code string) error {
	update := bson.M{
		"status": cinteractiond.ITStatusInit,
	}
	return r.DBUpdateCollAggregate(ctx, &collType{Code: code}, update)
}

// 发布类型
func (r typeRepo) LockType(ctx ddd.Context, code string) error {
	update := bson.M{
		"status": cinteractiond.ITStatusLock,
	}
	return r.DBUpdateCollAggregate(ctx, &collType{Code: code}, update)
}

// 发布类型
func (r typeRepo) UnlockType(ctx ddd.Context, code string) error {
	update := bson.M{
		"status": cinteractiond.ITStatusInit,
	}

	return r.DBUpdateCollAggregate(ctx, &collType{Code: code}, update)
}

// 彻底删除指定类型
func (r typeRepo) DestroyType(ctx ddd.Context, code string) error {
	if err := r.DBDestroyID(ctx, collNameType, code); err != nil {
		return err
	}
	r.DeleteCache(ctx, collType{Code: code})
	return nil
}
func (r typeRepo) ExistNameByCode(ctx ddd.Context, name, code string) (bool, error) {
	query := bson.M{
		"name": name,
	}
	if code != "" {
		query["_id"] = bson.M{"$neq": code}
	}
	return r.DBExists(ctx, collNameType, query)
}
func (r typeRepo) ExistCode(ctx ddd.Context, code string) (bool, error) {
	query := bson.M{
		"_id": code,
	}
	return r.DBExists(ctx, collNameType, query)
}
